package org.wbd.pklib.db.logic;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.hibernate.*;
import org.wbd.pklib.db.Book;
import org.wbd.pklib.db.DataBaseSession;
import org.wbd.pklib.db.Item;
import org.wbd.pklib.db.Loan;
import org.wbd.pklib.db.Repo;
import org.wbd.pklib.db.RepoUser;
import org.wbd.pklib.db.User;




/**
 * Singleton obslugujacy operacje na bazie zwiazane z uzytkownkiem
 */
public class UserLogic {
	private SessionFactory sessionFactory;
	static private UserLogic userLogic= null;
	
	private UserLogic(){
		sessionFactory = DataBaseSession.getInstance().getSessionFactory();		
	};
	
	  /**
	    * Zwraca instancje UserLogic
	    */
	static public UserLogic getInstance(){
		if (userLogic == null){
			userLogic = new UserLogic();
		}
		return userLogic;
	}
	
	  /**
	    * Probuje zalogowac uzytkownika o podanym loginie i hasle
	    */
	public LogicRespond logIn(String login, String password){	
				
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		List<User> result = session.createQuery("from User where login = '" + login + "'").list();
	
		LogicRespond logicRespond ;
		if (result.isEmpty()){			
			logicRespond = new LogicRespond("Nie ma takiego użytkownika", false);
		}
		else {
			String encryptedPass="";
			try {
				encryptedPass= MD5.encrypt(password);
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			 if (result.get(0).getPassword().compareTo(encryptedPass) == 0){
				 result.get(0).getRepoUsers().toString();
				 result.get(0).getItems().toString();
				 for (RepoUser ru: result.get(0).getRepoUsers()){
					 ru.getRepo().getItems().toString();
				 }
				 logicRespond = new LogicRespond("Uzytkownik " + login + " zalogowany ", true, (User)result.get(0));			 }
			 else {
				 logicRespond =  new LogicRespond("Niepoprawne hasło", false);
			 }
		}
		session.getTransaction().commit();
		session.close();		
		
		return logicRespond;
	}
	
	  /**
	    * Probuje zarejestrowac uzytkownika o podanych danych
	    */
	public LogicRespond register(String name, String surname, String login, String password, String email){
		try {
			String encryptedPass="";
			encryptedPass= MD5.encrypt(password);
			Session session = sessionFactory.openSession();
			session.beginTransaction();
			User newUser = new User(null, name, surname, login, encryptedPass, email,
					"user");
			session.save(newUser);
			session.getTransaction().commit();
			session.close();	
			return new LogicRespond("Zarejestrowano", true);
		} catch (Exception e) {
			return new LogicRespond("Istnieje juz uzytkownik o tym samym loginie", false);
		}		
	}	
	
	  /**
	    * Odlacza danego uzytkownika z repozytorium o podanym ip
	 *  
	    */
	public LogicRespond leaveRepo(User user, Integer repoId){
		LogicRespond logicRespond;
		try{
			Session session = sessionFactory.openSession();
			session.beginTransaction();					
			
			Repo repo =(Repo) session.get(Repo.class, repoId);			
			
			for (RepoUser ru : user.getRepoUsers()){
				if (ru.getRepo().getRepoId() == repo.getRepoId()){				
					user.getRepoUsers().remove(ru);				
					repo.getRepoUsers().remove(ru);
					
					break;
				}
			}		
			
			session.saveOrUpdate(user);
			session.saveOrUpdate(repo);		
			
			session.getTransaction().commit();
			session.close();
			logicRespond = new LogicRespond("You have leaved repo", true);
		}
		catch(Exception e){
			logicRespond = new LogicRespond("DB error", false);
		}
		return logicRespond;
	}
	
	  /**
	    * Zwraca liste repozytoriow do ktorych nalezy uzytkownik
	    */
	public LogicRespond getUserRepos(User user){
		LogicRespond logicRespond = new LogicRespond("Repos list", true);
		List<Object> reposList = new LinkedList<Object>();
		for (RepoUser ru : user.getRepoUsers()){
			reposList.add(ru.getRepo());
		}
		logicRespond.setResultList(reposList);
		return logicRespond;
	}	
	public LogicRespond getUser(Integer userId){
		LogicRespond logicRespond;
		try{
			Session session = sessionFactory.openSession();
			session.beginTransaction();					
			
			User user =(User) session.get(User.class, userId);		
			user.getRepoUsers().toString();
			user.getItems().toString();
			
			session.getTransaction().commit();
			session.close();
			logicRespond = new LogicRespond("User", true, user);
		}
		catch(Exception e){
			logicRespond = new LogicRespond("No users with specified id", false);
		}
		return logicRespond;
	}
	
	public LogicRespond getUserBooks(Integer userId){
		LogicRespond logicRespond;
		try{
			Session session = sessionFactory.openSession();
			session.beginTransaction();
			List<Object> result= session.createQuery("from Item where userId=" +userId).list();
			for (Object b : result){
				((Book) b).getItems().toString();
			}
			session.getTransaction().commit();
			session.close();
			logicRespond= new LogicRespond("books", true);
			logicRespond.setResultList(result);
			
		}
		catch(Exception e){
			logicRespond= new LogicRespond("DB error", false);
		}
		return logicRespond;
	}
	
	
}